package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.data.service.RichTextService;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.enums.DateTimeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.help.FormExplainHelp;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.paas.help.UserHelp;
import com.xbongbong.paas.help.service.impl.FormDataLinkDataUpdateGetServiceImpl;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.SearchCustomerCompanyModel;
import com.xbongbong.paas.pojo.IdNamePojo;
import com.xbongbong.paas.pojo.dto.FormDataAddGetDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.pojo.dto.LinkFormDataEditGetDTO;
import com.xbongbong.paas.pojo.dto.LinkFormDataFastAddGetDTO;
import com.xbongbong.paas.pojo.dto.ParseSingleRowDataDTO;
import com.xbongbong.paas.pojo.dto.UserAndDepartmentGetDTO;
import com.xbongbong.paas.pojo.vo.LinkFormDataAddGetVO;
import com.xbongbong.paas.pojo.vo.LinkFormDataEditGetVO;
import com.xbongbong.paas.pojo.vo.LinkResultDataVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.pojo.vo.UserAndDepartmentGetVO;
import com.xbongbong.paas.service.PaasLinkFormDataService;
import com.xbongbong.paas.service.impl.base.BaseFormDataService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.FormDataAddFormExplainHandlerName;
import com.xbongbong.parent.parse.data.FormDataUpdateGetAnalysisDataHelp;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.domain.entity.SearchCustomerCompanyEntity;
import com.xbongbong.pro.draft.pojo.vo.DraftExistVO;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.SoukeMealEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.InvoiceErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PaymentErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceLinkContractGetDTO;
import com.xbongbong.pro.invoice.pojo.vo.InvoiceLinkContractGetVO;
import com.xbongbong.pro.payment.pojo.dto.PaymentWriteOffGetDTO;
import com.xbongbong.pro.payment.pojo.vo.PaymentWriteOffGetVO;
import com.xbongbong.pro.permission.pojo.dto.VerifyAddPermissionDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyUpdatePermissionDTO;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ext.InvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.VisibleRangeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.PaymentBaseEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.InvoiceLinkContractEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PaymentTaskEnum;
import com.xbongbong.saas.enums.business.PaymentWriteOffEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.InvoiceCommonHelper;
import com.xbongbong.saas.help.SaasAddHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.InvoiceModel;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.service.PayPlanService;
import com.xbongbong.saas.service.PaymentService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

/**
 * 应用模块名称<p>
 * 代码描述<p>
 * Company: 逍邦网络科技有限公司<p>
 *
 * @author chenshan
 * @version v1.0
 * @since 2020-02-13 14:20
 */
@Service
public class PaasLinkFormDataServiceImpl extends BaseFormDataService implements PaasLinkFormDataService {

    private static final Logger LOG = LoggerFactory.getLogger(PaasLinkFormDataServiceImpl.class);

    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private FormExplainHelp formExplainHelp;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private SaasAddHelp saasAddHelp;
    @Resource
    private FormDataAddFormExplainHandlerName formDataAddFormExplainHandlerName;
    @Resource
    private FormDataLinkDataUpdateGetServiceImpl formDataLinkDataUpdateGetService;
    @Resource
    private SearchCustomerCompanyModel searchCustomerCompanyModel;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private UserHelp userHelp;
    @Resource
    private FormDataUpdateGetAnalysisDataHelp formDataUpdateGetAnalysisDataHelp;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private PayPlanService payPlanService;
    @Resource
    private PaymentService paymentService;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private InvoiceModel invoiceModel;
    @Resource
    private InvoiceCommonHelper invoiceCommonHelper;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private RichTextService richTextService;

    /**
     * 快捷新建表单数据
     *
     * @param linkFormDataFastAddGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public LinkFormDataAddGetVO linkFastAddGet(LinkFormDataFastAddGetDTO linkFormDataFastAddGetDTO) throws XbbException {
        VerifyAddPermissionDTO verifyAddPermissionDTO = new VerifyAddPermissionDTO();
        BeanUtil.copyProperties(linkFormDataFastAddGetDTO, verifyAddPermissionDTO);
        verifyAddPermissionDTO.setBusinessType(linkFormDataFastAddGetDTO.getLinkBusinessType());
        ProPermissionHelp.verifyAddPermission(verifyAddPermissionDTO);
        LinkFormDataAddGetVO linkFormDataAddGetVO = new LinkFormDataAddGetVO();
        try {
            String corpid = linkFormDataFastAddGetDTO.getCorpid();
            Integer linkBusinessType = linkFormDataFastAddGetDTO.getLinkBusinessType();
            Integer businessType = linkFormDataFastAddGetDTO.getBusinessType();
            Integer editable = linkFormDataFastAddGetDTO.getEditable();
            //父级业务的关联类型
            Integer topBusinessType = linkFormDataFastAddGetDTO.getTopBusinessType();
            //父级业务的id
            Long topId = linkFormDataFastAddGetDTO.getTopId();
            Long clueId = linkFormDataFastAddGetDTO.getClueId();
            SheetTypeEnum sheetTypeEnum = SheetTypeEnum.getByBusinessType(linkBusinessType);
            boolean sheetFlag = SheetTypeEnum.validateSheet(sheetTypeEnum);
            PaasFormEntityExt linkForm;
            if (sheetFlag) {
                linkBusinessType = sheetTypeEnum.getXbbRefTypeEnum().getCode();
            }
            Integer distributorMark = linkFormDataFastAddGetDTO.getDistributorMark();
            if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())) { // 经销商
                linkForm = paasFormModel.getByBusinessType4Distributor(linkBusinessType, corpid, distributorMark, null);
            } else {
                linkForm = paasFormModel.getByBusinessType(linkBusinessType, corpid);
            }
            Long formId = linkForm.getId();
            saasAddHelp.handleFormEntity(linkForm, linkFormDataFastAddGetDTO.getSaasMark(), linkFormDataFastAddGetDTO.getBusinessType());
            linkFormDataAddGetVO.setPaasFormEntity(linkForm);
            linkFormDataFastAddGetDTO.setFormId(linkForm.getId());
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            if ( Objects.isNull(paasFormExplainEntity) ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            // 查看是否能使用工商模糊查询
            Integer isBusiness = 0;
            SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
            if ( soukeEntity != null && soukeEntity.getExtraExpiry() > DateUtil.getInt() ) {
                isBusiness = 1;
            }
            linkFormDataAddGetVO.setIsBusiness(isBusiness);
            // 获取字段解释信息，并且过滤不可见字段 start
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(linkFormDataFastAddGetDTO, handlerExplainDTO, false);
            handlerExplainDTO.setExplainList(explainList);
            handlerExplainDTO.setPaasFormEntityExt(linkForm);
            HandlerExplainVO handlerExplainVO = formDataAddFormExplainHandlerName.handleExplain(handlerExplainDTO);
            if ( handlerExplainVO == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            explainList = handlerExplainVO.getHeadList();
            if ( sheetFlag ) {
                //如果是回/付款单、其他收入/支出单，则根据数据data内的回/付款单/其他收入/支出单类型重置sheetTypeEnum（前端传过来的businessType可能没有详细区分哪种类型回/付款单/其他收入/支出单）
                fundHelp.handlePaymentSheet(true, sheetTypeEnum, explainList, corpid, distributorMark);
                fundHelp.setBySheetType(linkForm, sheetTypeEnum);
            }
            String serialNo = "";
            for ( FieldAttrEntity fieldAttrEntity : explainList ) {
                // 获取流水号
                if (fieldAttrEntity.getFieldType() != null && fieldAttrEntity.getFieldType().equals(FieldTypeEnum.SERIALNO.getType()) && Objects.equals(fieldAttrEntity.getStrictController(), BasicConstant.ZERO)) {
                    serialNo = saasSaveHelp.getSerialNo(serialNo, corpid, formId, fieldAttrEntity);
                }
                if ( Objects.equals(fieldAttrEntity.getUnableEditMemo(), I18nMessageUtil.getMessage(StringConstant.AUTO_GEN_FIELD)) ||   Objects.equals(fieldAttrEntity.getUnableEditMemo(), I18nMessageUtil.getMessage(StringConstant.AUTO_GEN_FIELD, Locale.CHINA)) ) {
                    fieldAttrEntity.setVisible(0);
                }
            }
            linkFormDataAddGetVO.setSerialNo(serialNo);
            // 设置默认的关联数据
            FormDataAddGetDTO formDataAddGetDTO = new FormDataAddGetDTO();
            BeanUtil.copyProperties(linkFormDataFastAddGetDTO, formDataAddGetDTO);
            formDataAddGetDTO.setAppId(linkForm.getAppId());
            formDataAddGetDTO.setMenuId(linkForm.getMenuId());
            paasFormHelp.setDefaultLinkData(explainList, formDataAddGetDTO, handlerExplainVO);
            RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
            XbbRefTypeEnum linkXbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
            getShowColumnList(redundantTemplateTypeEnum, explainList, linkXbbRefTypeEnum);
            // 获取字段解释信息，并且过滤不可见字段 end
            // 新建表单时SaaS某些字段赋初始值
            if ( Objects.equals(linkFormDataFastAddGetDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode()) ) {
                FormatExplainDTO formatExplainDTO = new FormatExplainDTO();
                BeanUtil.copyProperties(linkFormDataFastAddGetDTO, formatExplainDTO);
                formatExplainDTO.setBusinessType(linkBusinessType);
                formatExplainDTO.setLinkBusinessType(businessType);
                formatExplainDTO.setExplainList(explainList);
                saasAddHelp.formatExplain(formatExplainDTO);
                explainList = formatExplainDTO.getExplainList();
                if ( Objects.equals(editable,0) ) {
                    for ( FieldAttrEntity fieldAttrEntity : explainList ) {
                        fieldAttrEntity.setEditable(0);
                    }
                }
                if ( Objects.nonNull(topBusinessType) && Objects.nonNull(topId) ){
                    // 封装入参
                    HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO = new HandlerExplainInLinkItemDTO();
                    BeanUtil.copyProperties(linkFormDataFastAddGetDTO, handlerExplainInLinkItemDTO);
                    putToDefaultAttr(corpid,topId,topBusinessType,explainList,paasFormExplainEntity,handlerExplainInLinkItemDTO);
                }
                if (Objects.nonNull(clueId)) {
                    // 线索转换客户时，点击添加联系人，这边需要给联系人的某些字段带默认值
                    putDefaultAttr(corpid, clueId, explainList, linkFormDataAddGetVO);
                }
            }
            // 在该种情况下表单是否存在草稿--理论上是没有的，所以默认填写没有
            linkFormDataAddGetVO.setDraftExistVO(new DraftExistVO());
            linkFormDataAddGetVO.setExplainList(explainList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormData数据库查询表单数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkFormDataAddGetVO;
    }


    private void putDefaultAttr(String corpid, Long clueId, List<FieldAttrEntity> explainList, LinkFormDataAddGetVO linkFormDataAddGetVO) throws XbbException{
        PaasFormDataEntityExt clueEntity = saasUpdateHelp.getFormData(clueId, corpid, XbbRefTypeEnum.CLUE.getCode());
        JSONObject data = clueEntity.getData();
        Object value;
        JSONObject defaultData = new JSONObject();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, ContactEnum.NAME.getAttr())) {
                value = data.get(ClueEnum.CONTACT.getAttr());
                if (Objects.nonNull(value)) {
                    defaultData.put(attr, value);
                }
            } else if (Objects.equals(attr, ContactEnum.PHONE.getAttr())) {
                JSONArray jsonArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, ClueEnum.PHONE.getAttr(), new JSONArray());
                JSONArray jsonArray = new JSONArray();
                if (Objects.nonNull(jsonArr)){
                    for (Object obj : jsonArr){
                        JSONObject json = (JSONObject) obj;
                        String phoneType = json.getString("text_1");
                        String phone = json.getString("text_2");
                        if (StringUtil.isNotEmpty(phoneType)) {
                            List<? extends FieldAttrEntity> items = fieldAttrEntity.getSubForm().getItems();
                            for (FieldAttrEntity subField : items) {
                                if (Objects.equals(subField.getAttr(), "text_1")) {
                                    List<ItemPoJo> items1 = subField.getItems();
                                    JSONObject typeObj = new JSONObject();
                                    boolean isOther = true;
                                    for (ItemPoJo itemPoJo : items1) {
                                        if (Objects.equals(itemPoJo.getValue(), phoneType)) {
                                            typeObj.put("text", itemPoJo.getText());
                                            typeObj.put("value", phoneType);
                                            isOther = false;
                                            break;
                                        }
                                    }
                                    if (isOther) {
                                        continue;
//                                        typeObj.put("text", phoneType);
//                                        typeObj.put("value", phoneType);
                                    }
                                    JSONObject valueObj = new JSONObject();
                                    valueObj.put("text_1", typeObj);
                                    if (StringUtil.isNotEmpty(phone)) {
                                        valueObj.put("text_2", phone);
                                    }
                                    jsonArray.add(valueObj);
                                    break;
                                }
                            }
                        }
                    }
                    defaultData.put(attr, jsonArray);
                }
            } else if (Objects.equals(attr, ContactEnum.ADDRESS.getAttr())) {
                value = data.get(ClueEnum.ADDRESS.getAttr());
                if (Objects.nonNull(value)) {
                    defaultData.put(attr, value);
                }
            }
        }
        if (!defaultData.isEmpty()) {
            linkFormDataAddGetVO.setData(defaultData);
        }
    }

    /**
     * 获取关联新建时展示的列
     *
     * @param redundantTemplateTypeEnum 业务类型枚举
     * @param explainList               解释
     * @return 需要展示的列
     */
    private void getShowColumnList(RedundantTemplateTypeEnum redundantTemplateTypeEnum, List<FieldAttrEntity> explainList, XbbRefTypeEnum linkTypeEnum) {
        Iterator<FieldAttrEntity> it = explainList.iterator();
        while (it.hasNext()) {
            FieldAttrEntity fieldAttrEntity = it.next();
            String attr = fieldAttrEntity.getAttr();
            switch (redundantTemplateTypeEnum) {
                case CUSTOMER:
                    // 客户里新建联系人去掉关联客户
                    if (Objects.equals(attr, ContactEnum.CUSTOMER_NAME.getAttr())) {
                        it.remove();
                    }
                    break;
                case SUPPLIER:
                    if (Objects.equals(attr, SupplierContactEnum.SUPPLIER_ID.getAttr())) {
                        it.remove();
                    }
                    break;
                case CONTRACT:
                case PAYMENT:
                    switch (linkTypeEnum) {
                        case WRITE_OFF_PREPAYMENT:
                            if (Objects.equals(attr, PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.BELONG_ID.getAttr()) || Objects.equals(attr, PaymentSheetEnum.PAYMENT_TIME.getAttr())) {
                                fieldAttrEntity.setParentAttr(ContractEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr());
                                if ( Objects.equals(attr, PaymentSheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                            }
                            if (Objects.equals(attr, PaymentSheetEnum.CUSTOMER_ID.getAttr())||Objects.equals(attr, PaymentSheetEnum.CONTRACT.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PaymentSheetEnum.PAYMENT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.PAYMENT_TASK.getAttr())) {
                                it.remove();
                            }
                            break;
                        case PAYMENT_SHEET:
                            if (Objects.equals(attr, PaymentSheetEnum.SHEET_NO.getAttr()) || Objects.equals(attr, PaymentSheetEnum.AMOUNT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.PAYMENT_TIME.getAttr()) || Objects.equals(attr, PaymentSheetEnum.BELONG_ID.getAttr())) {
                                fieldAttrEntity.setParentAttr(ContractEnum.ADD_PAYMENT_SHEET.getAttr());
                                if ( Objects.equals(attr, PaymentSheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                            }
                            if (Objects.equals(attr, PaymentSheetEnum.CUSTOMER_ID.getAttr())||Objects.equals(attr, PaymentSheetEnum.CONTRACT.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PaymentSheetEnum.PAYMENT.getAttr()) || Objects.equals(attr, PaymentSheetEnum.PAYMENT_TASK.getAttr())) {
                                it.remove();
                            }
                            break;
                        case PAYMENT_TASK:
                            if (Objects.equals(attr, PaymentTaskEnum.LINK_CUSTOMER.getAttr()) || Objects.equals(attr, PaymentTaskEnum.LINK_CONTRACT.getAttr())) {
                                fieldAttrEntity.setVisible(0);
                            }
                            break;
                        default:
                            if (Objects.equals(attr, PaymentEnum.PAYMENT_NO.getAttr()) || Objects.equals(attr, PaymentEnum.AMOUNT.getAttr()) || Objects.equals(attr, PaymentEnum.ESTIMATE_TIME.getAttr()) || Objects.equals(attr, PaymentEnum.STATUS.getAttr()) || Objects.equals(attr, PaymentEnum.PAYMENT_TYPE.getAttr()) || Objects.equals(attr, PaymentEnum.MEMO.getAttr())) {
                                fieldAttrEntity.setParentAttr(ContractEnum.ADD_PAYMENT.getAttr());
                            }
                            if (Objects.equals(attr, PaymentEnum.CUSTOMER.getAttr())||Objects.equals(attr, PaymentEnum.CONTRACT.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PaymentEnum.ADD_PAYMENT.getAttr())) {
                                it.remove();
                            }
                            if (Objects.equals(attr, PaymentEnum.SOURCE.getAttr())) {
                                it.remove();
                            }
                            break;
                    }
                    break;
                case PAY_PLAN:
                case PURCHASE:
                    switch (linkTypeEnum) {
                        case WRITE_OFF_PREPAY:
                            if (Objects.equals(attr, PaySheetEnum.WRITE_OFF_AMOUNT.getAttr()) || Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr()) || Objects.equals(attr, PaySheetEnum.REAL_PAY_TIME.getAttr())) {
                                fieldAttrEntity.setParentAttr(PurchaseEnum.ADD_WRITE_OFF_PREPAY.getAttr());
                                if ( Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                            }
                            if (Objects.equals(attr, PaySheetEnum.LINK_SUPPLIER.getAttr())||Objects.equals(attr, PaySheetEnum.LINK_PURCHASE.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PaySheetEnum.PAY_PLAN.getAttr())) {
                                it.remove();
                            }
                            break;
                        case PAY_SHEET:
                            if (Objects.equals(attr, PaySheetEnum.PAY_PLAN_NO.getAttr()) || Objects.equals(attr, PaySheetEnum.AMOUNT.getAttr()) || Objects.equals(attr, PaySheetEnum.REAL_PAY_TIME.getAttr()) || Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr())) {
                                fieldAttrEntity.setParentAttr(PurchaseEnum.ADD_PAY_SHEET.getAttr());
                                if ( Objects.equals(attr, PaySheetEnum.BELONG_ID.getAttr()) ) {
                                    fieldAttrEntity.setMultiple(0);
                                }
                            }
                            if (Objects.equals(attr, PaySheetEnum.LINK_SUPPLIER.getAttr())||Objects.equals(attr, PaySheetEnum.LINK_PURCHASE.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            // 去掉关联供应商等
                            if (Objects.equals(attr, PaySheetEnum.PAY_PLAN.getAttr())) {
                                it.remove();
                            }
                            break;
                        default:
                            // 采购合同新建页需要显示的回款列
                            if (Objects.equals(attr, PayPlanEnum.PAY_PLAN_NO.getAttr()) || Objects.equals(attr, PayPlanEnum.AMOUNT.getAttr()) || Objects.equals(attr, PayPlanEnum.ESTIMATE_TIME.getAttr()) || Objects.equals(attr, PayPlanEnum.STATUS.getAttr()) || Objects.equals(attr, PayPlanEnum.PAY_TYPE.getAttr()) || Objects.equals(attr, PayPlanEnum.MEMO.getAttr())) {
                                fieldAttrEntity.setParentAttr(PayPlanEnum.ADD_PAYPLAN.getAttr());
                            }
                            if (Objects.equals(attr, PayPlanEnum.LINK_SUPPLIER.getAttr())||Objects.equals(attr, PayPlanEnum.LINK_PURCHASE.getAttr())){
                                fieldAttrEntity.setVisible(0);
                            }
                            if (Objects.equals(attr, PayPlanEnum.ADD_PAYPLAN.getAttr())) {
                                it.remove();
                            }
                            break;
                    }
                    break;
                default:
                    break;
            }
        }
    }

    private List<FieldAttrEntity> putToDefaultAttr(String corpid,Long linkDataId, Integer linkBusinessType, List<FieldAttrEntity> explainList,PaasFormExplainEntity paasFormExplainEntity,HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("id", linkDataId);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, linkBusinessType, SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntityExt> paasFormDataEntityExts = paasEsModel.selectByCondition(linkBusinessType, new HashMap<>(BasicConstant.ONE), param, indexTypeEnum);
        if ( paasFormDataEntityExts.isEmpty() ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        PaasFormDataEntityExt paasFormDataEntityExt = paasFormDataEntityExts.get(BasicConstant.ZERO);
        Long dataId = paasFormDataEntityExt.getId();
        JSONObject dataList = paasFormDataEntityExt.getData();

        // 封装入参
        handlerExplainInLinkItemDTO.setLinkBusinessType(linkBusinessType);
        handlerExplainInLinkItemDTO.setExplainList(explainList);
        handlerExplainInLinkItemDTO.setLinkFormData(dataList);
        handlerExplainInLinkItemDTO.setLinkDataId(dataId);
        handlerExplainInLinkItemDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
        handlerExplainInLinkItemDTO.setProductList(new ArrayList<>());
        handlerExplainInLinkItemDTO.setPaasFormExplainEntity(paasFormExplainEntity);
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
        switch (xbbRefTypeEnum) {
            case PAY_PLAN:
                payPlanService.formatLinkAddExplain(handlerExplainInLinkItemDTO);
                break;
            case PAYMENT:
                paymentService.formatLinkAddExplain(handlerExplainInLinkItemDTO);
                break;
            default:
                break;
        }
        return explainList;
    }

    /**
     * 关联编辑,目前主要用于新建付款单和付款计划新建
     *
     * @param linkFormDataEditGetDTO
     * @return
     * @throws XbbException
     */
    @Override
    public LinkFormDataEditGetVO linkFastEditGet(LinkFormDataEditGetDTO linkFormDataEditGetDTO) throws XbbException {
        LinkFormDataEditGetVO linkFormDataEditGetVO = new LinkFormDataEditGetVO();
        try {
            VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO();
            BeanUtil.copyProperties(linkFormDataEditGetDTO, verifyUpdatePermissionDTO);
            ProPermissionHelp.verifyEditPermission(verifyUpdatePermissionDTO);
            Integer saasMark = linkFormDataEditGetDTO.getSaasMark();
            //先获取data数据
            String corpid = linkFormDataEditGetDTO.getCorpid();
            Long dataId = linkFormDataEditGetDTO.getDataId();
            PaasFormDataEntityExt formData;
            Integer businessType = linkFormDataEditGetDTO.getBusinessType();
            Integer linkBusinessType = linkFormDataEditGetDTO.getLinkBusinessType();
            Long topId = linkFormDataEditGetDTO.getTopId();
            Integer topBusinessType = linkFormDataEditGetDTO.getTopBusinessType();
            Integer editable = linkFormDataEditGetDTO.getEditable();
            SheetTypeEnum sheetTypeEnum = SheetTypeEnum.getByBusinessType(linkBusinessType);
            boolean sheetFlag = SheetTypeEnum.validateSheet(sheetTypeEnum);
            if (sheetFlag) {
                linkBusinessType = sheetTypeEnum.getXbbRefTypeEnum().getCode();
            }
            if ( Objects.equals(linkFormDataEditGetDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode()) ) {
                formData = saasUpdateHelp.getFormData(dataId, corpid, linkBusinessType);
            } else {
                // 没有saasMark标志的，现在全按paas应用来处理
                formData = paasFormDataModel.getByKey(dataId, corpid);
            }
            if ( formData == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            //拼装富文本
            richTextService.addRichTextByDataId(formData.getId(), corpid, formData.getFormId(), linkBusinessType, saasMark, DelEnum.NORMAL.getDel(), formData.getData());
            if ( FlowStatusEnum.inApproval(formData.getFlowStatus()) ) {
                throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200020);
            }
            PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formData.getFormId(), corpid);
            if ( paasFormEntityExt == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            saasAddHelp.handleFormEntity(paasFormEntityExt, linkFormDataEditGetDTO.getSaasMark(), linkFormDataEditGetDTO.getLinkBusinessType());
            linkFormDataEditGetVO.setPaasFormEntity(paasFormEntityExt);

            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formData.getFormId(), corpid);
            if ( paasFormExplainEntity == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            // ---- 获取用户和部门容器start
            UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
            BeanUtil.copyProperties(linkFormDataEditGetDTO, userAndDepartmentGetDTO);
            userAndDepartmentGetDTO.setExplainList(linkFormDataEditGetVO.getExplainList());
            UserAndDepartmentGetVO userAndDepartmentGetVO = userHelp.getUserDepartmentMap(userAndDepartmentGetDTO);
            Map<String, UserEntity> userMap = userAndDepartmentGetVO.getUserMap();
            Map<String, DepartmentEntity> departmentMap = userAndDepartmentGetVO.getDepartmentMap();
            // ---- 获取用户和部门容器end
            // 获取字段解释信息，并且过滤不可见字段
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(linkFormDataEditGetDTO, handlerExplainDTO, false);
            handlerExplainDTO.setExplainList(explainList);
            handlerExplainDTO.setPaasFormEntityExt(paasFormEntityExt);

            // 获取协同人和负责人
            paasFormHelp.getOwnerIdAndCoUserId(handlerExplainDTO, saasMark, businessType, linkFormDataEditGetDTO.getLinkBusinessType(), formData, userMap);
            List<String> ownerIds = handlerExplainDTO.getOwnerId();
            List<String> coUserIds = handlerExplainDTO.getCoUserId();
            List<ReturnUserAndDepartmentPojo> ownerIdPojoList = new ArrayList<>();
            List<ReturnUserAndDepartmentPojo> coUserIdPojoList = new ArrayList<>();
            if ( !Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), businessType) ) {
                ownerIds.forEach(owner -> {
                    UserEntity userEntity = userMap.get(owner);
                    if ( Objects.nonNull(userEntity) ) {
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                        BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                        returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                        ownerIdPojoList.add(returnUserAndDepartmentPojo);
                    }
                });
                coUserIds.forEach(coUser -> {
                    UserEntity userEntity = userMap.get(coUser);
                    if ( Objects.nonNull(userEntity) ) {
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                        BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                        returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                        coUserIdPojoList.add(returnUserAndDepartmentPojo);
                    }
                });
            } else {
                UserEntity userEntity = userMap.get(formData.getOwnerId());
                if ( Objects.nonNull(userEntity) ) {
                    ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                    BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                    returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                    ownerIdPojoList.add(returnUserAndDepartmentPojo);
                }
            }
            HandlerExplainVO handlerExplainVO = formDataAddFormExplainHandlerName.handleExplain(handlerExplainDTO);
            if ( handlerExplainVO == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            List<FieldAttrEntity> headList = handlerExplainVO.getHeadList();
            if (sheetFlag) {
                //如果是回/付款单，则根据数据data内的回/付款单类型重置sheetTypeEnum（前端传过来的businessType可能没有详细区分哪种类型回/付款单）
                sheetTypeEnum = fundHelp.getSheetTypeEnumByData(sheetTypeEnum, formData.getData());
                fundHelp.handlePaymentSheet(false, sheetTypeEnum, headList, corpid, paasFormEntityExt.getDistributorMark());
            }
            RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
            XbbRefTypeEnum linkXbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
            getShowColumnList(redundantTemplateTypeEnum, headList, linkXbbRefTypeEnum);
            linkFormDataEditGetVO.setExplainList(headList);

            // 查看是否能使用工商模糊查询
            Integer isBusiness = 0;
            SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
            if ( soukeEntity != null && soukeEntity.getExtraExpiry() > DateUtil.getInt() ) {
                isBusiness = 1;
            }
            linkFormDataEditGetVO.setIsBusiness(isBusiness);
            Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for ( FieldAttrEntity fieldAttrEntity : linkFormDataEditGetVO.getExplainList() ) {
                if ( Objects.equals(fieldAttrEntity.getUnableEditMemo(), I18nMessageUtil.getMessage(StringConstant.AUTO_GEN_FIELD)) ) {
                    fieldAttrEntity.setVisible(0);
                }
                // 存放字段容器
                explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
            }

            JSONObject data = formData.getData();
            if (Objects.equals(linkFormDataEditGetDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
                BeanUtil.copyProperties(linkFormDataEditGetDTO, saasAnalysisDataDTO);
                saasAnalysisDataDTO.setBusinessType(linkBusinessType);
                // saas特殊格式转换
                saasAnalysisDataDTO.setExplainMap(explainMap);
                saasUpdateHelp.formatData(saasAnalysisDataDTO, data);
//                if ( Objects.nonNull(topBusinessType) && Objects.nonNull(topId) ){
//                    // 封装入参
//                    HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO = new HandlerExplainInLinkItemDTO();
//                    BeanUtil.copyProperties(linkFormDataEditGetDTO, handlerExplainInLinkItemDTO);
//                    putToDefaultAttr(corpid,topId,topBusinessType,explainList,paasFormExplainEntity,handlerExplainInLinkItemDTO);
//                }

                // 编辑时saas字段显示特殊逻辑
                FormatExplainDTO formatExplainDTO = new FormatExplainDTO();
                BeanUtil.copyProperties(linkFormDataEditGetDTO, formatExplainDTO);
                formatExplainDTO.setExplainList(explainList);
                formatExplainDTO.setDataEntity(formData);
                formatExplainDTO.setResult(data);
                formatExplainDTO.setBusinessType(linkBusinessType);
                formatExplainDTO.setLinkBusinessType(businessType);
                formExplainHelp.formatExplain(formatExplainDTO, null);
                if ( Objects.equals(editable,0) ) {
                    for ( FieldAttrEntity fieldAttrEntity : explainList ) {
                        fieldAttrEntity.setEditable(0);
                    }
                }
                linkFormDataEditGetVO.setSaasSpecialParamPojo(formatExplainDTO.getSaasSpecialParamPojo());
            }
            if (XbbRefTypeEnum.hasVisibleRangeBusiness().contains(businessType)) {
                data.put(VisibleRangeEnum.VISIBLE_DEPT.getAttr(), ownerIds);
                data.put(VisibleRangeEnum.VISIBLE_USER.getAttr(), coUserIds);
                data.put(FieldTypeEnum.OWNERID.getAlias(), ownerIdPojoList);
            } else {
                data.put(FieldTypeEnum.OWNERID.getAlias(), ownerIdPojoList);
                data.put(FieldTypeEnum.COUSERID.getAlias(), coUserIdPojoList);
                if ( Objects.equals(linkFormDataEditGetDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())
                        && Objects.equals(data.getInteger(CustomerManagementEnum.IS_PUBLIC.getAttr()), 1) ) {
                    data.put(FieldTypeEnum.OWNERID.getAlias(), new ArrayList<>());
                    data.put(FieldTypeEnum.COUSERID.getAlias(), new ArrayList<>());
                }
            }
            data.put(FieldTypeEnum.DEPARTMENTID.getAlias(), formData.getDepartmentId());
            data.put(FieldTypeEnum.SERIALNO.getAlias(), formData.getSerialNo());
            // 解析数据信息
            ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
            BeanUtil.copyProperties(linkFormDataEditGetDTO, parseSingleRowDataDTO);
            parseSingleRowDataDTO.setDataJsonObject(data);
            parseSingleRowDataDTO.setExplainMap(explainMap);
            parseSingleRowDataDTO.setUserMap(userMap);
            parseSingleRowDataDTO.setDepartmentMap(departmentMap);
            ParseSingleRowDataVO parseSingleRowDataVO = formDataUpdateGetAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
            if ( parseSingleRowDataVO == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PARSE_SINGLE_ROW_DATA_FAILED);
            }
            LinkResultDataVO linkResultDataVO = parseSingleRowDataVO.getLinkResultDataVO();
            JSONObject result = parseSingleRowDataVO.getResult();
            // 获取关联数据的信息
            if ( linkResultDataVO != null && !linkResultDataVO.getLinkData().isEmpty() && !linkResultDataVO.getLinkDataSet().isEmpty() ) {
                FormDataUpdateGetDTO formDataGetDTO = new FormDataUpdateGetDTO();
                BeanUtil.copyProperties(linkFormDataEditGetDTO, formDataGetDTO);
                linkResultDataVO.setData(result);
                linkResultDataVO.setExplainMap(explainMap);
                linkResultDataVO.setUserMap(userMap);
                linkResultDataVO.setDepartmentMap(departmentMap);
                linkResultDataVO.setExplainList(explainList);
                result = formDataLinkDataUpdateGetService.formDataLinkDataGet(formDataGetDTO, linkResultDataVO);
            }
            formData.setData(result);
            linkFormDataEditGetVO.setData(formData);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormData数据库查询表单数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkFormDataEditGetVO;
    }

    @Override
    public PaymentWriteOffGetVO paymentWriteOffGet(PaymentWriteOffGetDTO paymentWriteOffGetDTO) throws XbbException {
        String corpid = paymentWriteOffGetDTO.getCorpid();
        Long paymentId = paymentWriteOffGetDTO.getDataId();
        PaymentEntityExt paymentEntityExt = paymentModel.getByKey(paymentId, corpid);
        if (Objects.isNull(paymentEntityExt)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        JSONObject data = JsonHelperUtil.getJSONObject(paymentEntityExt.getData());
        //有未收才能核销
        double unAmount = data.getDoubleValue(PaymentBaseEnum.UN_AMOUNT.getAttr());
        if (unAmount <= 0) {
            throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208069, PaymentErrorCodeEnum.API_ERROR_208069.getMsg());
        }
        Long formId = paymentEntityExt.getFormId();
        PaasFormEntityExt paymentForm = paasFormModel.getByKey(formId, corpid);
        PaymentWriteOffGetVO paymentWriteOffGetVO = new PaymentWriteOffGetVO();
        if (Objects.nonNull(paymentForm)) {
            PaasFormEntityExt sheetForm = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpid, paymentForm.getDistributorMark(), null);
            paymentWriteOffGetVO.setPaasFormEntity(sheetForm);
        }
        //应收款的信息
        Long contractId = data.getLong(PaymentBaseEnum.CONTRACT.getAttr());
        String contractNo = data.getString(PaymentBaseEnum.CONTRACT_LINK_TEXT.getAttr());
        List<IdNamePojo> contractPojo = Arrays.asList(new IdNamePojo(contractId, contractNo));
        List<IdNamePojo> paymentPojo = Arrays.asList(new IdNamePojo(paymentId, paymentEntityExt.getSerialNo()));
        //处理解释
        List<FieldAttrEntity> explainList = new ArrayList<>();
        Class<PaymentWriteOffEnum> paymentWriteOffEnumClass = PaymentWriteOffEnum.class;
        List<String> paymentWriteOffEnumAttrs = InitExplainsHelper.getBusinessEnumAttrs(paymentWriteOffEnumClass);
        JSONObject resultData = new JSONObject();
        resultData.put(PaymentWriteOffEnum.PAYMENT_UN_AMOUNT.getAttr(), unAmount);
        for (PaymentWriteOffEnum writeOffEnum : PaymentWriteOffEnum.values()) {
            FieldAttrEntity fieldAttrEntity = InitExplainsHelper.setField(paymentWriteOffEnumClass, paymentWriteOffEnumAttrs, writeOffEnum);
            fieldAttrEntity.setEditable(BasicConstant.ZERO);
            switch (writeOffEnum) {
                case CONTRACT:
                    fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contractPojo));
                    fieldAttrEntity.setShowType(ShowTypeEnum.NONE.getCode());
                    break;
                case PAYMENT:
                    fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(paymentPojo));
                    break;
                case PAYMENT_SHEET_ID:
                    fieldAttrEntity.setEditable(BasicConstant.ONE);
                    SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                    saasParticularAttributePoJo.setMultiCheck(false);
                    saasParticularAttributePoJo.setRelyAttr(PaymentWriteOffEnum.CONTRACT.getAttr());
                    saasParticularAttributePoJo.setRelyBusiness(XbbRefTypeEnum.CONTRACT.getCode());
                    fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
                    fieldAttrEntity.setBusinessType(XbbRefTypeEnum.PAYMENT.getCode());
                    fieldAttrEntity.setLinkedType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                    break;
                case PAYMENT_UN_AMOUNT:
                    fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(StringUtil.formatDecimal(unAmount)));
                    break;
                case AMOUNT:
                    saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                    saasParticularAttributePoJo.setRelyAttr(PaymentWriteOffEnum.PAYMENT_SHEET_ID.getAttr());
                    fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
                    break;
                default:
                    break;
            }
            explainList.add(fieldAttrEntity);
        }
        paymentWriteOffGetVO.setExplainList(explainList);
        paymentWriteOffGetVO.setData(resultData);
        return paymentWriteOffGetVO;
    }

    @Override
    public InvoiceLinkContractGetVO invoiceLinkContractGet(InvoiceLinkContractGetDTO invoiceLinkContractGetDTO) throws XbbException{
        String corpid = invoiceLinkContractGetDTO.getCorpid();
        Long invoiceId = invoiceLinkContractGetDTO.getDataId();
        JSONArray jsonArray = new JSONArray();
        //存放ownerId的数组
        JSONArray ownerJsonArray = new JSONArray();
        InvoiceLinkContractGetVO invoiceLinkContractGetVO = new InvoiceLinkContractGetVO();
        //在数据库中查询发票信息
        InvoiceEntityExt invoiceEntityExt = invoiceModel.getByKey(invoiceId, corpid);
        if (Objects.isNull(invoiceEntityExt)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        JSONObject data = invoiceEntityExt.getData();
        //开票金额小于0，提示不允许绑定
        double invoiceMoney = data.getDoubleValue(InvoiceEnum.TOTAL_MONEY.getAttr());
        if (invoiceMoney < 0) {
            throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_216054, InvoiceErrorCodeEnum.API_ERROR_216054.getMsg());
        }
        Long formId = invoiceEntityExt.getFormId();
        //获得销项发票
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
        //添加非空判断
        if (paasFormEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        //处理解释
        List<FieldAttrEntity> explainList = new ArrayList<>();
        Class<InvoiceLinkContractEnum> InvoiceLinkContractEnumClass = InvoiceLinkContractEnum.class;
        List<String> invoiceLinkContractEnumAttrs = InitExplainsHelper.getBusinessEnumAttrs(InvoiceLinkContractEnumClass);
        JSONObject resultData = new JSONObject();
        //获得登录人信息
        UserVO loginUser = invoiceLinkContractGetDTO.getLoginUser();
        //获取申请人信息
        JSONObject ownerIdJson = new JSONObject();
        ownerIdJson.put("id",invoiceEntityExt.getCreatorId());
        ownerIdJson.put("name", invoiceEntityExt.getCreatorName());
        ownerJsonArray.add(ownerIdJson);
        //将销项发票编号、开票金额、关联客户、开票日期放入返回的dataList中
        String serialNo = invoiceEntityExt.getSerialNo();
        resultData.put(InvoiceLinkContractEnum.SHEET_NO.getAttr(), serialNo);
        resultData.put(InvoiceLinkContractEnum.TOTAL_MONEY.getAttr(), invoiceMoney);
        //获得关联客户的名称
        String customerName = data.getString(InvoiceEnum.CUSTOMER_NAME_LINK_TEXT.getAttr());
        JSONObject jsonObject = new JSONObject();
        String attr = InvoiceEnum.CUSTOMER_NAME.getAttr();
        Long customerId = data.getLong(attr);
        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, customerId);
        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, customerName);
        jsonArray.add(jsonObject);
        resultData.put(attr, jsonArray);
        resultData.put("invoiceId", invoiceId);
        resultData.put(InvoiceEnum.APPLY_USER.getAttr(), ownerJsonArray);
        //开票日期
        Long invoiceDate = Long.valueOf(data.getInteger(InvoiceEnum.INVOICE_DATE.getAttr()));
        resultData.put(InvoiceLinkContractEnum.INVOICE_DATE.getAttr(), invoiceDate);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        handlerExplainDTO.setLoginUser(loginUser);
        handlerExplainDTO.setUserId(invoiceLinkContractGetDTO.getUserId());

        //获取发票的表单模板解释
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if(Objects.isNull(explainEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        String explains = explainEntity.getExplains();
        List<FieldAttrEntity> fieldAttrEntities = JsonHelperUtil.parseArray(explains, FieldAttrEntity.class);
        for (InvoiceLinkContractEnum linkContractEnum : InvoiceLinkContractEnum.values()) {
            FieldAttrEntity fieldAttrEntity = InitExplainsHelper.setField(InvoiceLinkContractEnumClass, invoiceLinkContractEnumAttrs, linkContractEnum);
            fieldAttrEntity.setEditable(BasicConstant.ZERO);
            switch (linkContractEnum) {
                case SHEET_NO:
                    List<IdNamePojo> invoicePojo = Arrays.asList(new IdNamePojo(invoiceId, serialNo));
                    fieldAttrEntity.setShowType(ShowTypeEnum.ALL.getCode());
                    fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(invoicePojo));
                    break;
                case TOTAL_MONEY:
                    fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(StringUtil.formatDecimal(invoiceMoney)));
                    break;
                case CONTRACT_ID:
                    //获得当前用户在表单模版界面是否有可编辑关联合同的权限
                    Boolean flag = invoiceCommonHelper.checkInvoiceHighLevelEdit(fieldAttrEntities, handlerExplainDTO,InvoiceEnum.CONTRACT_ID);
                    if (flag){
                        fieldAttrEntity.setEditable(BasicConstant.ONE);
                    }
                    Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains, null);
                    FieldAttrEntity fieldAttrEntityContract = explainMap.get(InvoiceLinkContractEnum.CONTRACT_ID.getAttr());
                    SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                    if (Objects.nonNull(fieldAttrEntityContract)){
                        saasParticularAttributePoJo = fieldAttrEntityContract.getSaasParticularAttributePoJo();
                    }
                    //设置为单选
                    fieldAttrEntity.setFieldType(FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
                    fieldAttrEntity.setLinkedType(XbbRefTypeEnum.CONTRACT.getCode());
                    saasParticularAttributePoJo.setMultiCheck(false);
                    fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
                    break;
                case INVOICE_DATE:
                    fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(invoiceDate));
                    fieldAttrEntity.setDateType(DateTimeEnum.TIME.getType());
                    //获得当前用户在表单模版界面是否有可编辑开票日期的权限
                    Boolean dateFlag = invoiceCommonHelper.checkInvoiceHighLevelEdit(fieldAttrEntities, handlerExplainDTO,InvoiceEnum.INVOICE_DATE);
                    if (dateFlag){
                        fieldAttrEntity.setEditable(BasicConstant.ONE);
                    }
                    break;
                default:
                    break;
            }
            explainList.add(fieldAttrEntity);
        }
        invoiceLinkContractGetVO.setExplainList(explainList);
        invoiceLinkContractGetVO.setData(resultData);
        paasFormEntityExt.setName(OperateModuleTypeEnum.INVOICE_LINK_CONTRACT.getName());
        invoiceLinkContractGetVO.setPaasFormEntity(paasFormEntityExt);
        return invoiceLinkContractGetVO;
    }



}
